package com.example.socket.client;

import com.example.socket.core.Session;
import com.example.socket.filter.session.NettySession;
import com.example.socket.handler.Dispatcher;
import com.example.socket.handler.SnGenerator;
import com.example.socket.thread.DelayedElement;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;

import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;

/**
 * 工厂创建的客户端对象
 */
public class SimpleClient extends AbstractClient<NettySession> {

    @SuppressWarnings("rawtypes")
    public SimpleClient(Dispatcher dispatcher, InetSocketAddress address,
                        Bootstrap connector, ClientFactory factory, boolean keepAlive,
                        SnGenerator generator,
                        ConcurrentHashMap<Integer, SocketFuture> futures,
                        DelayQueue<DelayedElement<?>> delays, boolean sendHeartBeat) {

        this.dispatcher = dispatcher;
        this.address = address;
        this.connector = connector;
        this.factory = factory;
        this.keepAlive = keepAlive;
        this.generator = generator;
        this.futures = futures;
        this.delays = delays;
        this.sendProxy = new SendProxyFactory(this, factory.responseTimeout);
        this.sendHeartBeat = sendHeartBeat;
        this.type = TCP;
        this.timeOut = factory.responseTimeout;
    }

    @Override
    protected void createChannel() throws InterruptedException {
        ChannelFuture future = connector.connect(address);
        future.sync();
        Channel channel = future.channel();
        this.channel = channel;
        session = NettySession.client(sessionId, channel);
    }

    @Override
    protected void createSession() {
        Session oldSession = session;
        session = NettySession.client(sessionId, channel);
        if (oldSession != null) {
            session.bindContext(oldSession.getContext());
        }
    }
}